package com.easy.framework.web.config;

import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.easy.framework.web.i18n.CustomLocaleChangeInterceptor;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import java.nio.charset.Charset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        config.setSerializerFeatures(
                // 保留map空的字段
                SerializerFeature.WriteMapNullValue,
                // 将String类型的null转成""
                SerializerFeature.WriteNullStringAsEmpty,
//				// 将Number类型的null转成0
                SerializerFeature.WriteNullNumberAsZero,
                // 将List类型的null转成[]
                SerializerFeature.WriteNullListAsEmpty,
//				// 将Boolean类型的null转成false
//				SerializerFeature.WriteNullBooleanAsFalse,
                // 避免科学计数法表示大数字
                SerializerFeature.WriteBigDecimalAsPlain,
                // 避免循环引用
                SerializerFeature.DisableCircularReferenceDetect);
        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
        serializeConfig.put(Long.class, com.alibaba.fastjson.serializer.ToStringSerializer.instance);
        serializeConfig.put(Long.TYPE, com.alibaba.fastjson.serializer.ToStringSerializer.instance);
//		serializeConfig.put(Date.class, com.alibaba.fastjson.serializer.ToStringSerializer.instance);
//		serializeConfig.put(LocalDate.class, com.alibaba.fastjson.serializer.ToStringSerializer.instance);
//		serializeConfig.put(LocalDateTime.class, com.alibaba.fastjson.serializer.ToStringSerializer.instance);
        config.setSerializeConfig(serializeConfig);
        config.setDateFormat("yyyy-MM-dd HH:mm:ss");

        converter.setFastJsonConfig(config);
        converter.setDefaultCharset(Charset.forName("UTF-8"));
        List<MediaType> supportedMediaTypes = new ArrayList<>();
        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
        converter.setSupportedMediaTypes(supportedMediaTypes);
        converters.add(0, converter);
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
        DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
        registrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        registrar.setDateTimeFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        registrar.registerFormatters(registry);
    }

    @Bean
    public MessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasenames("i18n","i18n.messages");
        messageSource.setDefaultEncoding("UTF-8");
        messageSource.setUseCodeAsDefaultMessage(true);
//        messageSource.setCacheSeconds(30);  // 开发时可设短缓存
        return messageSource;
    }

    /**
     * 定义一个 LocaleResolver bean，用于处理当前用户会话中的语言环境。
     *
     * LocaleResolver 用于解析当前请求的语言环境，通常会根据Session中的信息来判断。
     * 在这里我们使用的是 SessionLocaleResolver，它会将用户选择的语言存储在Session中，
     * 这样用户在后续请求中可以保持相同的语言环境。
     *
     * @return 返回配置好的 LocaleResolver
     */
    @Bean
    public LocaleResolver localeResolver() {
        // 创建一个 SessionLocaleResolver 实例
        SessionLocaleResolver slr = new SessionLocaleResolver();

        // 设置默认的语言环境为简体中文 (zh_CN)
        // 当用户没有明确设置语言时，应用默认使用简体中文
        slr.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);

        return slr;
    }

    /**
     * 配置国际化拦截器，用于监听用户请求中的语言切换参数。
     *
     * 该方法会添加一个自定义的拦截器 CustomLocaleChangeInterceptor，目的是监听用户请求中的语言切换请求，
     * 并更新当前会话的语言环境。
     *
     * @param registry 拦截器注册器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册自定义的语言环境切换拦截器
        // 该拦截器会监听请求中是否包含语言参数（例如：?lang=zh_CN），
        // 如果有，就会根据该参数改变当前用户的语言环境。
        registry.addInterceptor(new CustomLocaleChangeInterceptor());
    }
}